package com.cecsmsserve.util;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.cecsmsserve.entity.User;
import com.cecsmsserve.service.IUserService;
import com.cecsmsserve.util.exception.CustomException;
import com.cecsmsserve.util.result.CommonResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import static com.cecsmsserve.util.JWTUtil.SECRET;

//jwt拦截器
@Component
public class JWTInterceptor implements HandlerInterceptor {

    private static final Logger log= LoggerFactory.getLogger(JWTInterceptor.class);

    @Resource
    private IUserService userService;

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handle) throws IOException {
        String requestURI = request.getRequestURI();
        log.info("请求路径: {}", requestURI);
        
        //1.从http请求的header中获取token
        String token=request.getHeader("token");
        if(StrUtil.isBlank(token)){
            //如果没拿到，再去参数中拿 /api/user？token=xxx
            token=request.getParameter("token");
        }
        //2.开始执行认证
        if(StrUtil.isBlank(token)){
            log.error("无token，请求路径: {}", requestURI);
            throw new CustomException("无token，请重新登录");
        }
        //获取token中的uId
        String uId;
        User user;
        try{
            uId= JWT.decode(token).getAudience().get(0);
            user=userService.getById(Integer.parseInt(uId));
        }catch (Exception e){
            String errMsg="token验证失败，请重新登录";
            log.error(errMsg + ", 请求路径: " + requestURI + ", token=" + token, e);
            throw new CustomException(errMsg);
        }
        if(user==null){
            log.error("用户不存在，请求路径: {}, userId: {}", requestURI, uId);
            throw new CustomException("用户不存在，请重新登录");
        }
        try{
            //用户密码加签验证token
            JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(SECRET)).build();
            jwtVerifier.verify(token);//验证token
        }catch (JWTVerificationException e){
            log.error("token验证失败，请求路径: {}, userId: {}", requestURI, uId);
            throw new CustomException("token验证失败，请重新登录");
        }
        log.info("token验证成功，放行，请求路径: {}, userId: {}", requestURI, uId);
        return true;
    }
}
